package com.baosight.ice;

import com.baosight.ice.util.PrxHelper;
import com.zeroc.Ice.*;
import com.zeroc.Ice.LocatorPrx;
import com.zeroc.IceBox.ServiceManagerPrx;
import com.zeroc.IceGrid.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.ldap.PagedResultsResponseControl;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class IceTester {
    public static void main(String args[]) throws PermissionDeniedException, NodeNotExistException, NodeUnreachableException, ServerNotExistException, DeploymentException, ApplicationNotExistException {
        String[] connectParam = new String[]{
                "--Ice.Default.Locator=IceGrid/Locator :tcp -h 10.25.25.129 -p 12000"
        };
        Communicator communicator = Util.initialize(connectParam);
        LocatorPrx defaultLocator = communicator.getDefaultLocator();
        QueryPrx queryPrx = PrxHelper.getServicePrxPriCache(communicator, QueryPrx.class, "IceGrid/Query");
        //NodeObserverPrx nodeObserverPrx = PrxHelper.getServicePrxPriCache(communicator, NodeObserverPrx.class, "IceGrid/NodeObserver");
        //LocatorFinderPrx locatorFinderPrx=PrxHelper.getServicePrxPriCache(communicator,LocatorFinderPrx.class,"Ice/LocatorFinder");
        LocatorPrx locatorPrx=PrxHelper.getServicePrxPriCache(communicator,LocatorPrx.class,"IceGrid/Locator");

        AdminSessionPrx adminSession = RegistryPrx.checkedCast(communicator.stringToProxy("IceGrid/Registry")).createAdminSession("1", "");
        AdminPrx admin = adminSession.getAdmin();
        String[] allAdapterIds = admin.getAllAdapterIds();

        String nodeName = "XCYBER";
        NodeInfo nodeInfo = admin.getNodeInfo(nodeName);

        ObjectPrx nodeAdmin = admin.getNodeAdmin(nodeName);
        //System.out.println("nodeAdmin ids:"+ Arrays.asList(nodeAdmin.ice_ids()));

        String facet = nodeAdmin.ice_getFacet();
//        System.out.println(facet);
//        NodeObserverPrx nodeObserverPrx=NodeObserverPrx.checkedCast(nodeAdmin);
        String serverId = "DemoService-Server-1";
        ObjectPrx serverAdmin = admin.getServerAdmin(serverId);
        ServerInfo serverInfo = admin.getServerInfo(serverId);
        LoadInfo nodeLoad = admin.getNodeLoad(nodeName);
        String applicationName = "XCYBER";
        ApplicationInfo applicationInfo = admin.getApplicationInfo(applicationName);
        //NodeObserverPrx nodeObserverPrx=null;
        //关闭服务
        ServiceManagerPrx svcmgr =ServiceManagerPrx.checkedCast(serverAdmin, "IceBox.ServiceManager");
        //System.out.println("ServerAdmin ids:"+Arrays.asList(admin.getServerAdmin(serverId).ice_ids()));
        svcmgr.shutdown();

        Identity identity = new Identity();
        identity.category = admin.getServerAdminCategory();
        identity.name = "DemoServiceManager-1  ";
        PropertiesAdminPrx propertiesAdminPrx = PropertiesAdminPrx.checkedCast(admin.ice_identity(identity));
        Map<String, String> propertiesForPrefix = propertiesAdminPrx.getPropertiesForPrefix("");
        System.out.println(propertiesForPrefix);
        //        String finderStr="Ice/LocatorFinder";
//        com.zeroc.Ice.RouterFinderPrx finder = com.zeroc.Ice.RouterFinderPrx.uncheckedCast(
//                communicator.stringToProxy(finderStr));
//        finder.getRouter()
        System.out.println("end");
    }

    public static class PrxHelper {

        private static Map<String, ObjectPrx> prxMap = new ConcurrentHashMap<>();
        private static Logger logger = LoggerFactory.getLogger(com.baosight.ice.util.PrxHelper.class);
        private static String METHODNAME = "checkedCast";
        private static String LOCATOR = "--Ice.Default.Locator";

        public static <T extends ObjectPrx> T getServicePrxPriCache(Communicator communicator, Class<T> tClass, String identity) {
            String key = tClass.getName() + "_" + identity;
            if (prxMap.containsKey(key)) {
                return (T) prxMap.get(key);
            } else {
                T prxInstance = getServicePrxPri(communicator, tClass, identity);
                if (prxInstance != null) {
                    prxMap.put(key, prxInstance);
                    return prxInstance;
                }
                return null;
            }
        }

        public static <T extends ObjectPrx> T getServicePrxPri(Communicator communicator, Class<T> tClass, String identity) {
            ObjectPrx objectPrx = communicator.stringToProxy(identity);
            Method checkedCast = null;
            try {
                checkedCast = tClass.getMethod(METHODNAME, ObjectPrx.class);
                return (T) checkedCast.invoke(null, objectPrx);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(MessageFormat.format(
                        "{0} don't have method {1}", tClass.getName(), METHODNAME));
            } catch (Throwable t) {
                throw new RuntimeException(t);
            }
        }

    }
}
